package com.zbiti.anvil.basic.admin.gateway;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zbiti.anvil.wf.api.exception.WfException;
import com.zbiti.sdk.common.enums.HttpMethod;
import com.zbiti.sdk.common.security.utils.AESUtil;
import com.zbiti.sdk.common.utils.AssertUtils;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Model;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@SpringBootTest
public class CommonTester {

    @Autowired
    private RepositoryService repositoryService;

    /**
     * 用于将activiti流程图转化为flowable流程图
     */
    @Test
    public void convertJsonToXmlModel() throws IOException {

        List<Model> list = repositoryService.createModelQuery().list();

        for (Model model : list) {
            // 获取流程数据
            Model modelData = repositoryService.getModel(model.getId());
            // 判断流程设计数据是否存在
            byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());
            AssertUtils.assertNotNull(bytes, "流程模型为空，请先设计流程并成功保存");
            // 部署流程信息
            JsonNode modelNode;
            try {
                modelNode = new ObjectMapper().readTree(bytes);
            } catch (IOException e) {
                throw new WfException("读取流程模型文件异常", e);
            }
            BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            // 转换为XML字节数组
            byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(bpmnModel);
            repositoryService.addModelEditorSource(model.getId(), bpmnBytes);
        }

    }


    @Test
    public void testJoin() {
        List<String> sqls = new ArrayList<>();
        System.out.println("sql=" + String.join(" OR ", sqls));
        sqls.add("select * from a");
        sqls.add("select * from b");
        System.out.println("sql=" + String.join(" OR ", sqls));
    }

    @Test
    public void testReg() {
        String reg = "system:(role|menu|dict):(insert|update|delete)";
        String[] values = {"system:role:insert", "system:menu:update", "system:dict:delete", "system:cache:delete"};
        for (String value : values) {
            System.out.printf("%s=%s\n", value, value.matches(reg));
        }
    }

    @Test
    public void testHttpMethod() {
        Assertions.assertTrue(HttpMethod.POST.matches("poSt"));
    }

    @Test
    public void testStream() {
        ThreadLocal<String> my = new ThreadLocal<>();
        my.set("name");

        List<String> arr = Arrays.asList("1", "2", "3", "4", "5", "a", "b", "c", "d", "e");
        arr.forEach(e -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ignore) {
            }
            System.out.println(Thread.currentThread().getId() + ":" + e + ":" + my.get());
        });
        System.out.println("==============");
        final AtomicInteger a = new AtomicInteger(10);
        arr.parallelStream().forEach(e -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignore) {
            }
            System.out.println(Thread.currentThread().getId() + ":" + e + ":" + a.getAndIncrement() + ":" + my.get());
        });
        System.out.println("==============");

        System.out.println(a.get());
    }

    @Test
    public void testStream2() {
        StringBuffer buffer = new StringBuffer(2);

        final List<String> list = new ArrayList<>(2);
        final List<String> arr = Arrays.asList("1", "2", "3", "4", "5", "a", "b", "c", "d", "e");

        arr.parallelStream().forEach(e -> {
            buffer.append(e);
            list.add(e);
        });
        System.out.println("==============");

        System.out.println(buffer);
        System.out.println(String.join(",", list));
    }

    @Test
    public void testAnvilEncrypt() {
        String username = AESUtil.anvilEncryptProperty("11", "z6^_0");
        System.out.println(username);
        String pwd = AESUtil.anvilEncryptProperty("22", "6^_0");
        System.out.println(pwd);
    }

    @Test
    public void test2025() {
        // 十六进制
        System.out.println(solution("40"));
        System.out.println(solution("400"));
        System.out.println(solution("17"));
        System.out.println(solution("-1"));

        // 求和
//        System.out.println(solution("[-1,0,1,2,-1,-4]"));
//        System.out.println(solution("[-2,0,4,2,-1,-4]"));
//        System.out.println(solution("[-2,0,-4,-2,-1,-4]"));
//        System.out.println(solution("[-2,0,-4,-2,-1]"));

        // 括号匹配
//        System.out.println(solution("[({}()[])]")); // true
//        System.out.println(solution("[({})[])]")); // false
//        System.out.println(solution("[({}()[]]")); // false
//        System.out.println(solution("[{}(()[])]")); // true

        // 括号匹配
//        System.out.println(solution("Hello")); // hello
//        System.out.println(solution("HeLLo")); // HELLO
//        System.out.println(solution("We")); // we
//        System.out.println(solution("HelP")); // help

    }
    private static String solution(String value) {
        // value是输入的值，比如输入值30（注意：在这个方法里，传入的字符串“30”）
        // if(value<"0"||value>"2147483647") {
        //    return "false";
        // }

        int a=Integer.parseInt(value);
        String res="";

        while(a!=0) {
            int i=a%16;

            if(i==10) {
                res="A"+res;
            }

            else if(i==11) {
                res="B"+res;
            }

            else if(i==12) {
                res="C"+res;
            }

            else if(i==13) {
                res="D"+res;
            }

            else if(i==14) {
                res="E"+res;
            }

            else if(i==15) {
                res="F"+res;
            }

            else {
                res=i+res;
            }

            a/=16;
        }

        return res;
    }
}
